<?php

/**
 * Pes for PHP 5.3+
 *
 * Copyright (c) 2013 phpeskill.com (http://www.pescms.com)
 *
 * For the full copyright and license information, please view
 * the file LICENSE.md that was distributed with this source code.
 */

namespace App\Admin;

use Core\Db\Db as Db;
use Model\Admin\OptionModel as OptionModel;
use Core\Cache\FileCache as FileCache;

/**
 * 系统设置
 * @author LazyPHP
 * @version 1.0
 */
class Setting extends Common {

    private $logo = array(
        'field_name' => 'logo',
        'name' => 'logo',
        'type' => 'thumb'
    );

    /**
     * 网站系统设置
     */
    public function index() {
        $list = OptionModel::getSiteSetting();
        foreach ($list as $key => $value) {
            $setting[$value['option_name']] = $value;
        }
        $this->logo['value'] = $setting['logo']['value'];
        $this->assign('logo', $this->logo);
        $this->assign('setting', $setting);
        $this->display();
    }

    /**
     * 更新网站设置
     * 网站更新的代码属于一个宽松的行为
     * 仅判断是否有提交内容
     */
    public function updateSiteSetting() {
        $data['sitestatus'] = is_numeric($_POST['sitestatus']) ? $_POST['sitestatus'] : '请选择网站当前状态';
        if ($data['sitestatus'] == '0') {
            $data['closeReason'] = $this->is_p('closeReason', '请填写网站关闭的原因');
        }
        $data['sitetitle'] = $this->is_p('sitetitle', '请填写一个响亮的网站标题');
        $data['siteurl'] = $this->is_p('siteurl', '请填写网站域名');
        $data['logo'] = $this->is_p('logo', '您还没上传网站LOGO');
        $data['seo_keyword'] = $this->p('seo_keyword');
        $data['seo_description'] = $this->p('seo_description');
        //因为提交的会有JS代码，所以不进行转义
        $data['footerCode'] = $this->p('footerCode', FALSE);
        $db = $this->db('option');
        foreach ($data as $key => $value) {
            $db->where("option_name = :option_name")->save(array('option_name' => $key, 'value' => $value));
        }
        $this->success('更新网站设置成功!', '/?g=Admin&m=Setting&a=index');
    }

    /**
     * 系统扩展变量
     */
    public function expand() {
        $db = $this->db('option');
        $list = $db->where('id = 12')->find();
        $this->assign('list', json_decode($list['value'], true));
        $this->display();
    }

    /**
     * 更新系统扩展变量
     */
    public function updateExpand() {
        $totalKey = count($_POST['key']);
        if ($totalKey != count($_POST['value'])) {
            $this->error('提交的键名和值长度不一致!');
        }
        for ($i = 0; $i < $totalKey; $i++) {
            $newArray[$_POST['key'][$i]] = $_POST['value'][$i];
        }
        $db = $this->db('option');
        $updateResult = $db->where('id = 12')->save(array('value' => json_encode($newArray)));
        $this->determineSqlExecResult($updateResult, '更新系统变量失败');
        $this->success('更新系统变量成功!', $this->url('Admin-Setting-expand'));
    }

    /**
     * URL格式设置
     */
    public function urlModel() {
        $db = $this->db('option');
        $result = $db->where('option_name = "urlModel"')->find();
        $this->assign(json_decode($result['value'], true));
        $this->display();
    }

    /**
     * 更新URL格式设置
     */
    public function updateUrlModel() {
        $index = $this->is_p('index', '请选择是否隐藏index.php');
        $urlModel = $this->is_p('urlModel', '请选择URL模式');

        $url = json_encode(array('index' => $index, 'urlModel' => $urlModel));
        $db = $this->db('option');
        $result = $db->where('option_name = "urlModel"')->save(array('value'=>$url));
        $this->determineSqlExecResult($result, '更新URL格式失败');
        $this->success('更新URL格式成功', $this->url('Admin-Setting-urlModel'));
    }

    /**
     * 检查更新
     */
    public function update() {
        $this->updateInfo();
        $this->display();
    }

    /**
     * 执行更新
     */
    public function doUpdate() {
        $this->outFlush('<p>执行更新动作，请勿关闭浏览器!</p>');
        $result = $this->updateInfo();
        $this->determineSqlExecResult($result, '当前没有更新');
        //更新代码
        if (!empty($result['file'])) {
            $this->get_file('http://www.pescms.com' . $result['file'], './upload/update');
            $this->zip($result['file']);
        }
        //更新数据库
        if (!empty($result['sql'])) {
            $this->get_file('http://www.pescms.com' . $result['sql'], './upload/update');
            $this->sql($result['sql']);
        }
        //更新版本
        $db = $this->db('option');
        $updateVersion = $db->where('id = 13')->save(array("value" => $result['version']));
        if (empty($updateVersion)) {
            $this->outFlush('<p>更新系统版本出错!</p>');
        } else {
            $this->deleteUpdateFile();
            $this->outFlush("<p>系统更新完毕!当前版本为：{$result['version']}</p>");
            $this->outFlush('<script>location.href = "/?g=Admin&m=Setting&a=update";</script>', 3);
        }
    }

    /**
     * 获取更新信息
     */
    private function updateInfo() {
        $db = $this->db('option');
        $version = $db->where('id = 13')->find();
        $this->assign('version', $version['value']);
        $content = file_get_contents('http://www.pescms.com/Update-index-version-' . urlencode($version['value']));
        $result = (array) simplexml_load_string($content);
        switch ($result['mes']) {
            case '-1':
                return false;
                break;
                ;
            case '-2':
                $this->error('提交参数失败');
                break;
        }
        $this->assign('result', $result);
        return $result;
        ;
    }

    /**
     * 文件下载
     * 源码来自:http://hawaii162162.iteye.com/blog/803491
     * @param type $url 下载的URL
     * @param type $folder 保存目录
     * @return boolean 返回结果
     */
    private function get_file($url, $folder = "./") {
        $this->outFlush("<p>远程下载更新文件中{$url}...</p>");
        set_time_limit(24 * 60 * 60); // 设置超时时间   
        $destination_folder = $folder . '/'; // 文件下载保存目录，默认为当前文件目录   
        if (!is_dir($destination_folder)) { // 判断目录是否存在   
            $this->mkdirs($destination_folder); // 如果没有就建立目录   
        }
        $newfname = $destination_folder . basename($url); // 取得文件的名称   
        //防止多次下载，引起主站负担过重.
        if (is_file($newfname)) {
            return true;
        }
        $file = fopen($url, "rb"); // 远程下载文件，二进制模式   
        if ($file) { // 如果下载成功   
            $newf = fopen($newfname, "wb"); // 远在文件文件   
            if ($newf) // 如果文件保存成功   
                while (!feof($file)) { // 判断附件写入是否完整   
                    fwrite($newf, fread($file, 1024 * 8), 1024 * 8); // 没有写完就继续   
                }
        }
        if ($file) {
            fclose($file); // 关闭远程文件   
        }
        if ($newf) {
            fclose($newf); // 关闭本地文件   
        }
        return true;
    }

    /**
     * 创建目录
     * 源码来自:http://hawaii162162.iteye.com/blog/803491
     * @param type $path 目录名称
     * @param type $mode 目录权限
     * @return boolean 返回结果
     */
    private function mkdirs($path, $mode = "0755") {
        if (!is_dir($path)) { // 判断目录是否存在   
            $this->mkdirs(dirname($path), $mode); // 循环建立目录     
            mkdir($path, $mode); // 建立目录   
        }
        return true;
    }

    /**
     * 进行安装包解压覆盖动作
     * @param type $file
     */
    private function zip($file) {
        $this->outFlush("<p>执行更新文件解压中...</p>");
        $zip = new \ZipArchive;
        if ($zip->open("./upload/update/" . basename($file)) === TRUE) {
            $zip->extractTo('./');
            $zip->close();
            $this->outFlush("<p>系统文件更新完毕!</p>");
        } else {
            $this->outFlush("<p>安装文件解压失败，请检查您的服务器是否已开启ZipArchive</p>");
            exit;
        }
    }

    /**
     * 进行数据库更新
     */
    private function sql($file) {
        $this->outFlush("<p>执行数据库更新...</p>");
        if (is_file("./upload/update/" . basename($file))) {
            //解压文件
            $zip = new \ZipArchive;
            if ($zip->open("./upload/update/" . basename($file)) === TRUE) {
                $zip->extractTo('./upload/update/');
                $zip->close();
            }

            $db = $this->db('');
            $fh = file("./upload/update/update.sql");
            $sql = '';
            foreach ($fh as $key => $value) {
                $sql .= $value;
            }
            $db->alter($sql);
            $this->outFlush("<p>更新数据库成功!</p>");
        } else {
            $this->outFlush("<p>执行更新的数据库文件不存在!</p>");
            exit;
        }
    }

    /**
     * 清空下载的更新文件
     */
    private function deleteUpdateFile() {
        $dirName = './upload/update';
        if ($handle = opendir($dirName)) {
            while (false !== ($item = readdir($handle))) {
                if ($item != "." && $item != "..") {
                    if (!is_dir("$dirName/$item")) {
                        unlink("$dirName/$item");
                    }
                }
            }
        }
    }

    /**
     * 打印更新的信息
     * @param type $mes 信息
     * @param type $sleep 停留多少秒
     */
    private function outFlush($mes, $sleep = '1') {
        ob_flush();
        flush();
        echo $mes;
        sleep($sleep);
    }

    /**
     * 上传格式
     */
    public function uploadForm() {
        $db = $this->db('option');
        $result = $db->where('option_range = "upload"')->order('id asc')->select();
        foreach ($result as $key => $value) {
            $list[$value['option_name']] = implode(',', json_decode($value['value']));
        }
        $this->assign('list', $list);
        $this->display();
    }

    /**
     * 更新上传格式
     */
    public function updateUoloadForm() {
        $db = $this->db('option');
        foreach ($_POST as $key => $value) {
            $update = $db->where('option_name = :option_name')->save(array('option_name' => $key, 'value' => json_encode(explode(',', $value))));
        }
        $this->success('更新成功!', $this->url("Admin-Setting-uploadForm"));
    }

}
